package persistentie;

import com.mysql.jdbc.PreparedStatement;
import domein.Gebruiker;
import domein.Webinar;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.ResultSet;
import java.sql.Time;
import java.util.ArrayList;
import java.sql.Date;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Robin
 */
public class WebinarMapper extends AbstractMapper<Integer, Webinar> {

    //SQL statements
    public final String LIJST_WEBINARS = "SELECT * FROM 'Webinar' ORDER BY datum,beginU,onderwerp";
    //geef de geplande webinars die nog moeten plaatsvinden
    public final String GEEFGEPLANDEWEBINARS = "SELECT * FROM  `Webinar` WHERE gebruikerid =? AND (datum > CURDATE( )AND afgelopen = FALSE)";
    public final String WEBINARTOEVOEGEN = "INSERT INTO webinar (onderwerp, commentaar,afbeelding, datum,beginU,eindU,afgelopen,gebruikerID) VALUES (?,?,?,?,?,?,?,?)";
    public final String GEEFINGESCHREVENWEBINARS = "SELECT w.webinarID, w.onderwerp, w.commentaar, w.afbeelding, w.datum, w.beginU, w.eindU, w.afgelopen, w.gebruikerID, w.actief FROM webinarVolger wv JOIN webinar w ON wv.webinarID=w.webinarID WHERE wv.GebruikerID=? AND w.afgelopen=FALSE";
    public final String GEEFGEPASSEERDEWEBINARS = "SELECT w.webinarID, w.onderwerp, w.commentaar, w.afbeelding, w.datum, w.beginU, w.eindU, w.afgelopen, w.gebruikerID,w.actief FROM webinarVolger wv RIGHT JOIN webinar w ON wv.webinarID=w.webinarID WHERE (wv.GebruikerID=? or w.GebruikerID=?) AND w.afgelopen=TRUE";
    public final String LIJST_WEBINARVOLGERS = "SELECT g.gebruikerID,g.voornaam,g.familienaam FROM `WebinarVolger` wv JOIN gebruiker g on wv.gebruikerID=g.gebruikerID WHERE wv.webinarID=?";
    public final String GEEFBESCHIKBAREWEBINARS = "SELECT DISTINCT w.* FROM webinar w LEFT JOIN webinarvolger wv ON w.webinarid=wv.webinarid WHERE (wv.gebruikerID!=? OR wv.gebruikerid is null) AND (wv.webinarID NOT IN(SELECT webinarID FROM webinarVolger WHERE gebruikerID=?) OR wv.webinarID is null) AND w.gebruikerID!=? AND afgelopen=false AND actief=false";
    public final String VOEGWEBINARVOLGERTOE = "INSERT INTO  WebinarVolger (`WebinarID` ,`GebruikerID`) VALUES (?,  ?);";
    public final String VERWIJDERWEBINARVOLGER = "DELETE FROM webinarvolger WHERE webinarID=? AND gebruikerID=?";
    public final String LIJST_VRAAGENANTWOORD = "SELECT vraag.tekst as vraag, antwoord.tekst as antwoord FROM vraag LEFT JOIN antwoord on vraag.vraagID = antwoord.vraagID WHERE vraag.webinarID = ?";
    public final String GEEFACTIEVEWEBINARS = "SELECT DISTINCT w.webinarID, w.onderwerp, w.commentaar, w.afbeelding, w.datum, w.beginU, w.eindU, w.afgelopen, w.gebruikerID, w.actief FROM webinarVolger wv RIGHT JOIN webinar w ON wv.webinarID=w.webinarID WHERE (wv.GebruikerID=? OR w.gebruikerID=?) AND (w.afgelopen=FALSE AND w.actief=TRUE)";
    public final String STARTWEBINAR = "UPDATE Webinar SET actief=TRUE WHERE webinarID=?";
    public final String STOPWEBINAR = "UPDATE Webinar SET actief=FALSE, afgelopen=TRUE WHERE webinarID=?";
    public final String WEBINARWIJZIGEN = "UPDATE Webinar SET  onderwerp=?, commentaar=?, afbeelding=?, datum=?, beginU=?, eindU=?, afgelopen=FALSE, actief=FALSE WHERE  webinarID =?";
    public final String WEBINARVERWIJDEREN1 = "DELETE FROM Webinar WHERE webinarID=?";
    public final String WEBINARVERWIJDEREN2 = "DELETE FROM WebinarVolger WHERE webinarID=?";

    @Override
    public HashMap<Integer, Webinar> geefMap() {
        HashMap<Integer, Webinar> webinars = new HashMap<Integer, Webinar>();

        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(LIJST_WEBINARS);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = rs.getString("afbeelding");
                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");

                Webinar g = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.put(Integer.valueOf(webinarID), g);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public HashMap<Integer, Webinar> geefWebinars(int gid) {
        HashMap<Integer, Webinar> webinars = new HashMap<Integer, Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFGEPLANDEWEBINARS);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");

                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");

                if (is.equals(null)) {
                    leesAfbeelding(afbeelding, is);
                }

                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");
                Webinar g = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.put(Integer.valueOf(webinarID), g);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public void voegNieuweWebinarToe(Webinar webinar) {

        FileInputStream fis;
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(WEBINARTOEVOEGEN);
            ps.setString(1, webinar.getOnderwerp());
            ps.setString(2, webinar.getCommentaar());

            File file = new File(webinar.getAfbeelding());


            fis = new FileInputStream(file);
            ps.setBinaryStream(3, (InputStream) fis, (int) file.length());
            //ps.setString(3, webinar.getAfbeelding());

            ps.setDate(4, webinar.getDag());
            ps.setTime(5, webinar.getStartU());
            ps.setTime(6, webinar.getEindU());
            ps.setBoolean(7, webinar.isAfgelopen());
            ps.setInt(8, webinar.getInstructeur());
            ps.executeUpdate();
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public ArrayList<Webinar> geefGepasseerdeWebinars(int gid) {
        ArrayList<Webinar> webinars = new ArrayList<Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFGEPASSEERDEWEBINARS);

            ps.setInt(1, gid);
            ps.setInt(2, gid);

            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");

                if (is.equals(null)) {
                    leesAfbeelding(afbeelding, is);
                }

                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");

                Webinar w = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.add(w);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public ArrayList<String> geefVraagEnAntwoord(int wid) {
        ArrayList<String> s = new ArrayList<String>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(LIJST_VRAAGENANTWOORD);

            ps.setInt(1, wid);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                String vraag = "Vraag: " + rs.getString("vraag");
                String antwoord = "Antwoord: " + rs.getString("antwoord");
                s.add(vraag);
                s.add(antwoord);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    @Override
    public ArrayList<Webinar> geefGeplandeWebinars(int gid) {
        ArrayList<Webinar> webinars = new ArrayList<Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFGEPLANDEWEBINARS);
            ps.setInt(1, gid);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");

                leesAfbeelding(afbeelding, is);

                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");
                Webinar webinar = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU, afgelopen, instructeur, actief);

                webinars.add(webinar);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public ArrayList<Webinar> geefIngeschrevenWebinars(int gid) {
        ArrayList<Webinar> webinars = new ArrayList<Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFINGESCHREVENWEBINARS);

            ps.setInt(1, gid);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");

                if (is.equals(null)) {
                    leesAfbeelding(afbeelding, is);
                }

                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");

                Webinar g = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.add(g);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public ArrayList<Webinar> geefActieveWebinars(int gid) {
        ArrayList<Webinar> webinars = new ArrayList<Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFACTIEVEWEBINARS);

            ps.setInt(1, gid);
            ps.setInt(2, gid);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");

                if (is.equals(null)) {
                    leesAfbeelding(afbeelding, is);
                }

                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");

                Webinar g = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.add(g);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public ArrayList<Webinar> geefBeschikbareWebinars(int gid) {
        ArrayList<Webinar> webinars = new ArrayList<Webinar>();
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(GEEFBESCHIKBAREWEBINARS);

            ps.setInt(1, gid);
            ps.setInt(2, gid);
            ps.setInt(3, gid);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                int webinarID = rs.getInt("webinarID");
                String onderwerp = rs.getString("onderwerp");
                String commentaar = rs.getString("commentaar");
                String afbeelding = "src/images/" + onderwerp + webinarID + ".gif";

                InputStream is = rs.getBinaryStream("afbeelding");
                leesAfbeelding(afbeelding, is);


                Date datum = rs.getDate("datum");
                Time beginU = rs.getTime("beginU");
                Time eindU = rs.getTime("eindU");
                boolean afgelopen = rs.getBoolean("afgelopen");
                int instructeur = rs.getInt("gebruikerID");
                boolean actief = rs.getBoolean("actief");

                Webinar g = new Webinar(webinarID, onderwerp, commentaar, afbeelding, datum, beginU, eindU,
                        afgelopen, instructeur, actief);
                webinars.add(g);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinars;
    }

    @Override
    public HashMap<Integer, Gebruiker> geefVolgersWebinar(int webID) {
        HashMap<Integer, Gebruiker> webinarVolgers = new HashMap<Integer, Gebruiker>();

        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(LIJST_WEBINARVOLGERS);
            ps.setInt(1, webID);
            ResultSet rs = ps.executeQuery();


            while (rs.next()) {
                ps.setInt(1, webID);

                int gid = rs.getInt("gebruikerID");
                String voornaam = rs.getString("voornaam");
                String familienaam = rs.getString("familienaam");

                Gebruiker g = new Gebruiker(gid, voornaam, familienaam, null);
                webinarVolgers.put(Integer.valueOf(gid), g);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return webinarVolgers;
    }

    @Override
    public void voegWebinarVolgerToe(int gebruikerID, int webinarID) {
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(VOEGWEBINARVOLGERTOE);
            ps.setInt(1, gebruikerID);
            ps.setInt(2, webinarID);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void verwijderWebinarVolger(int gebruikerID, int webinarID) {
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(VERWIJDERWEBINARVOLGER);
            ps.setInt(1, webinarID);
            ps.setInt(2, gebruikerID);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void startWebinar(int webinarID) {
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(STARTWEBINAR);
            ps.setInt(1, webinarID);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopWebinar(int webinarID) {
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(STOPWEBINAR);
            ps.setInt(1, webinarID);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void wijzigWebinar(Webinar web) {
        FileInputStream fis;
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(WEBINARWIJZIGEN);
            ps.setString(1, web.getOnderwerp());
            ps.setString(2, web.getCommentaar());
            File file = new File(web.getAfbeelding());
            fis = new FileInputStream(file);
            ps.setBinaryStream(3, (InputStream) fis, (int) file.length());

            ps.setDate(4, web.getDag());
            ps.setTime(5, web.getStartU());
            ps.setTime(6, web.getEindU());
            ps.setInt(7, web.getWebinarID());
            ps.executeUpdate();
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void verwijderWebinar(int webid) {
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(WEBINARVERWIJDEREN1);
            ps.setInt(1, webid);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            PreparedStatement ps = (PreparedStatement) DbConnection.getInstance().getConnection().prepareStatement(WEBINARVERWIJDEREN2);
            ps.setInt(1, webid);
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //hulpmethode voor het lezen van een afbeelding

    private void leesAfbeelding(String bestandsnaam, InputStream fis) {
        FileOutputStream fos = null;
        try {
            File image = new File(bestandsnaam);
            fos = new FileOutputStream(image);
            byte[] buffer = new byte[1];

            while (fis.read(buffer) >= 0) {
                fos.write(buffer);
            }


            fos.close();
        } catch (Exception ex) {
            Logger.getLogger(WebinarMapper.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
